<?php
	include_once "config_db.php";
	require_once 'doublelist.class.php';
	
	$database = 'mymap';
	
	if (!mysql_connect($db_host, $db_user, $db_pwd))
	die("Can't connect to database");
	
	if (!mysql_select_db($database))
	die("Can't select database");
	
	mysql_query("SET NAMES 'utf8'");
	$function_name = $_REQUEST["function_name"];
	
	static $maps = array();
	static $open_list = array();

	if($function_name == "getLastID") {
		$table_input = $_REQUEST["table_input"];
		getLastID($table_input);
	} elseif($function_name == "getNodeForSegment") {
		$segment_id = $_REQUEST["segment_id"];
		getNodeForSegment($segment_id);
	} elseif($function_name == "insertNodeTo") {
		insertNodeTo();
	}  elseif($function_name == "find_nodeTo") {
		$start_node = $_REQUEST["start_node"];
		$end_node = $_REQUEST["end_node"];
		find_nodeTo($start_node, $end_node);
	}
	function getLastID($table_input) {
		$result = mysql_query("SELECT id FROM {$table_input}");
		if(mysql_num_rows($result) == 0) {
			$return['id'] = 0;
		} else {
			while($data = mysql_fetch_array($result)) {
				$return['id'] = $data["id"];
			}	
		}
		echo json_encode($return);
	}
	function getNodeForSegment($segment_id) {
		$query = "SELECT lat, lng FROM segment, node ".
				 "WHERE segment.id = ".$segment_id.
				 " AND node.id = segment.start_node";
		$result = mysql_query($query);
		while($data = mysql_fetch_array($result)) {
			$node['lat'] = $data["lat"];
			$node['lng'] = $data["lng"];			
			$return['start_node'] = $node;
		}	
		
		$query = "SELECT lat, lng FROM segment, node ".
				 "WHERE segment.id = ".$segment_id.
				 " AND node.id = segment.end_node";
				 
		$result = mysql_query($query);
		while($data = mysql_fetch_array($result)) {
			$node['lat'] = $data["lat"];
			$node['lng'] = $data["lng"];			
			$return['end_node'] = $node;
		}	
		echo json_encode($return);
	}
	function insertNodeTo() {
		set_time_limit(36000);
		$query = "SELECT id FROM segment";
		$result_segment = mysql_query($query);
		
		while($data_segment = mysql_fetch_array($result_segment)) {
			$query = "SELECT nd FROM segment_nd WHERE segment_id = ".$data_segment['id'];
			$result_segment_nd = mysql_query($query);
			$length = mysql_num_rows($result_segment_nd);
			for($i = 0; $i < $length; $i++) {
				mysql_data_seek($result_segment_nd, $i);
				$data_segment_nd = mysql_fetch_array($result_segment_nd);
				$node_id = $data_segment_nd['nd'];
				$query = "SELECT nodeTo FROM node WHERE id = ".$node_id;
				$result_nodeTo = mysql_query($query);
				$data_nodeTo = mysql_fetch_array($result_nodeTo);
				$new_nodeTo = $data_nodeTo['nodeTo'];
				if($i == 0) {
					mysql_data_seek($result_segment_nd, ($i + 1));
					$data_segment_nd = mysql_fetch_array($result_segment_nd);
					$new_nodeTo = $new_nodeTo.$data_segment_nd['nd'].", ";
					$query = "UPDATE node SET nodeTo = '".$new_nodeTo."' WHERE id = ".$node_id;
					mysql_query($query);					
				} elseif($i > 0 && $i < ($length - 1)) {
					mysql_data_seek($result_segment_nd, ($i - 1));
					$data_segment_nd = mysql_fetch_array($result_segment_nd);
					$new_nodeTo = $new_nodeTo.$data_segment_nd['nd'].", ";
					mysql_data_seek($result_segment_nd, ($i + 1));
					$data_segment_nd = mysql_fetch_array($result_segment_nd);
					$new_nodeTo = $new_nodeTo.$data_segment_nd['nd'].", ";
					$query = "UPDATE node SET nodeTo = '".$new_nodeTo."' WHERE id = ".$node_id;
					mysql_query($query);
				} else {
					mysql_data_seek($result_segment_nd, ($i - 1));
					$data_segment_nd = mysql_fetch_array($result_segment_nd);
					$new_nodeTo = $new_nodeTo.$data_segment_nd['nd'].", ";	
					$query = "UPDATE node SET nodeTo = '".$new_nodeTo."' WHERE id = ".$node_id;
					mysql_query($query);
				}	
			}			
		}			
		echo "Finish!";
	}
	/*function insertNodeTo() {
		set_time_limit(36000);
		$query = "SELECT id FROM node";
		$result_node = mysql_query($query);
		mysql_data_seek($result_node, 4641);
		$query = "SELECT id, start_node, end_node FROM segment";
		$result_segment = mysql_query($query);

		$i = 0;
		$count = 0;
		while($data_node = mysql_fetch_array($result_node)) {
			$nodeTo = '';
			$isExist = false;
			$node_id = $data_node['id'];			
			while($data_segment = mysql_fetch_array($result_segment)) {
				$segment_id = $data_segment['id'];
				$query = "SELECT nd FROM segment_nd WHERE segment_id = ".$segment_id;
				$result_segment_nd = mysql_query($query);
				$i = 0;
				while($data_segment_nd = mysql_fetch_array($result_segment_nd)) {
					$node_detail_id = $data_segment_nd['nd'];
					if($node_detail_id == $node_id) {
						if($i > 0) {
							mysql_data_seek($result_segment_nd, 0);
							$data_segment_nd = mysql_fetch_array($result_segment_nd);
							$temp = $data_segment_nd['nd'].", "; 
							$nodeTo = $nodeTo.$temp;	
						}
						if($i < (mysql_num_rows($result_segment_nd) - 1)) {
							mysql_data_seek($result_segment_nd, (mysql_num_rows($result_segment_nd) - 1));
							$data_segment_nd = mysql_fetch_array($result_segment_nd);
							$temp = $data_segment_nd['nd'].", "; 
							$nodeTo = $nodeTo.$temp;	
						}		
						$isExist = true;
						break;						
					} 
					$i++;
				}	
			}	
			if($isExist) {
				$nodeTo = substr($nodeTo, 0, strlen($nodeTo) - 2);
				$query = "UPDATE node SET nodeTo = '".$nodeTo."' WHERE id = ".$node_id;
				$result_insert = mysql_query($query);
			} 			
			mysql_data_seek($result_segment, 0);
		}			
		echo "Finish!";
	}*/
	function find_nodeTo($start_node, $end_node) {		
				
		$open_list = new DoublyLinkedList();
		$close_list = new DoublyLinkedList();
		$query = "SELECT id, lat, lng, nodeTo FROM node WHERE id = ".$start_node;
		$result_startnode = mysql_query($query);			
		$data_startnode_nodeTo = mysql_fetch_array($result_startnode);
		$start_node_lat = $data_startnode_nodeTo['lat'];
		$start_node_lng = $data_startnode_nodeTo['lng'];
		$temp['g'] = 0;
		$temp['h'] = 0;
		$temp['f'] = 0;
		$temp['lat'] = $start_node_lat;
		$temp['lng'] = $start_node_lng;
		$temp['parent'] = null;
		$open_list->insertLast($start_node, $temp);
		$found = false;
		while($open_list->totalNodes() != 0) {
			$best_node = $open_list->getBestNode();
			$id = $best_node->getId();
			$data_best_node = $best_node->getData();
			
			$temp['g'] = $data_best_node['g'];
			$temp['h'] = $data_best_node['h'];
			$temp['f'] = $data_best_node['f'];
			$temp['lat'] = $data_best_node['lat'];
			$temp['lng'] = $data_best_node['lng'];
			$temp['parent'] = $data_best_node['parent'];		
			$close_list->insertLast($id, $temp);
			$open_list->deleteNode($id);
			
			if($id != $end_node) {					
				$query = "SELECT id, lat, lng, nodeTo FROM node WHERE id = ".$id;
				$result = mysql_query($query);			
				$data_nodeTo = mysql_fetch_array($result);
				$start_node_lat = $data_nodeTo['lat'];
				$start_node_lng = $data_nodeTo['lng'];
				$nodeTo = process_str($data_nodeTo['nodeTo']);			
				for($i = 0; $i < sizeof($nodeTo); $i++) {	
					$query = "SELECT lat, lng FROM node WHERE id = ".$end_node;		
					$result_nodeTo_endnode = mysql_query($query);
					$data_nodeTo_endnode = mysql_fetch_array($result_nodeTo_endnode);	
					$end_node_lat = $data_nodeTo_endnode['lat'];
					$end_node_lng = $data_nodeTo_endnode['lng'];
					
					$query = "SELECT lat, lng FROM node WHERE id = ".$nodeTo[$i];		
					$result_nodeTo_approving = mysql_query($query);
					$data_nodeTo_approving = mysql_fetch_array($result_nodeTo_approving);
					$node_approved_lat = $data_nodeTo_approving['lat'];
					$node_approved_lng = $data_nodeTo_approving['lng'];
					
					$dis_node_start_to_approving = cal_distance($start_node_lat, $start_node_lng, $node_approved_lat, $node_approved_lng);
					$dis_node_approving_to_end = cal_distance($node_approved_lat, $node_approved_lng, $end_node_lat, $end_node_lng);
					$sum_dis = $dis_node_start_to_approving + $dis_node_approving_to_end;
					
					$temp['g'] = $dis_node_start_to_approving;
					$temp['h'] = $dis_node_approving_to_end;
					$temp['f'] = $sum_dis;
					$temp['lat'] = $node_approved_lat;
					$temp['lng'] = $node_approved_lng;
					$temp['parent'] = $id;
					
					
					if($open_list->findNode($nodeTo[$i])) {
						$open_list->updateNode($nodeTo[$i], $temp);
					} else {
						$open_list->insertLast($nodeTo[$i], $temp);
					}
				}
			} else {
				$found = true;
				break;
			}
		}
		
		if($found) {
			$node_array = array();			
			$current = $close_list->getLastNode();
			$data = $current->getData();
			$temp_result['id'] = $current->getId();
			$temp_result['lat'] = $data['lat'];
		    $temp_result['lng'] = $data['lng'];
			$node_array[] = $temp_result;
			while($data['parent'] != $start_node) {
				$current = $close_list->getNode($data['parent']);
				$data = $current->getData();
				$temp_result['id'] = $current->getId();
				$temp_result['lat'] = $data['lat'];
				$temp_result['lng'] = $data['lng'];
				$node_array[] = $temp_result;
			}
			$current = $close_list->getFirstNode();
			$data = $current->getData();
			$temp_result['id'] = $current->getId();
			$temp_result['lat'] = $data['lat'];
		    $temp_result['lng'] = $data['lng'];
			$node_array[] = $temp_result;
			
			echo '{"way":'.json_encode($node_array).'}';
		} else {
			return NULL;
		}		
	}
	
	function cal_distance($lat1, $lng1, $lat2, $lng2) {
		$R = 6371; // km
		$dLat = ($lat2 - $lat1)*pi()/180;
		$dLon = ($lng2 - $lng1)*pi()/180;
		$lat1 = $lat1*pi()/180;
		$lat2 = $lat2*pi()/180;
		
		$a = sin($dLat/2) * sin($dLat/2) +
				sin($dLon/2) * sin($dLon/2) * cos($lat1) * cos($lat2); 
		$c = 2 * atan2(sqrt($a), sqrt(1 - $a)); 
		$d = $R * $c;
		return $d;
	}
	
	function cal_real_distance($array_way) {
		$dis = 0;
		for($i = 0; $i < sizeof($array_way); $i++) {
			if($i > 0) {
				$end_point = $array_way[$i];	
				$dis += cal_distance($start_point, $end_point);
			}
			$start_point = $array_way[$i];
		}
		return $dis;
	}
	
	function process_str($str) {
		$nodeTo_id = array();
		$num_char = substr_count($str, ",");
		for($i = 0; $i < $num_char; $i++) {			
			$str_temp = substr($str, 0, strpos($str, ","));
			$str = substr($str, strpos($str, ",") + 2, strlen($str));
			$nodeTo_id[$i] = $str_temp;
		}
		return $nodeTo_id;
	}
?>